﻿using System;
using System.Diagnostics.CodeAnalysis;
using System.Text.Json.Serialization;

namespace Sdcb.SparkDesk;

/// <summary>
/// Represents the chat property for chat parameters.
/// </summary>
public class ChatRequestParameters
{
    /// <summary>
    /// Determines the randomness of the result. The higher the value, the higher the randomness, and the more likely the same question will get different answers. Range: [0,1], default: 0.5
    /// </summary>
    [JsonPropertyName("temperature")]
    public float Temperature { get; set; } = 0.5f;

    /// <summary>
    /// Specifies the maximum length of model response in tokens, Range: [1,4096] for v1.5, [1, 8192] for v2.0/v3.0/v3.5, default: 2048.
    /// </summary>
    [JsonPropertyName("max_tokens")]
    public int MaxTokens { get; set; } = 2048;

    /// <summary>
    /// Specifies the number of candidate sequences generated by the model will be trimmed down to "k" before sampling. Higher values means the model will be more consistent, lower values means the model will be more creative. Range: [1, 6], default: 4.
    /// </summary>
    [JsonPropertyName("top_k")]
    public int TopK { get; set; } = 4;

    /// <summary>
    /// A unique identifier for the current user conversation session. Can be used by the developer to keep track of the user's inputs and outputs.
    /// </summary>
    [JsonPropertyName("chat_id")]
    public string? ChatId { get; set; }
}

/// <summary>
/// Represents the chat property for chat parameters.
/// </summary>
internal class ChatRequestParametersInternal : ChatRequestParameters
{
    public ChatRequestParametersInternal()
    {
    }

    [SetsRequiredMembers]
    public ChatRequestParametersInternal(ModelVersion version, ChatRequestParameters? req = null)
    {
        if (req != null)
        {
            Temperature = req.Temperature;
            MaxTokens = req.MaxTokens;
            TopK = req.TopK;
            ChatId = req.ChatId;
        }
        
        Domain = version switch
        {
            ModelVersion.V1_5 => "general",
            ModelVersion.V2 => "generalv2",
            ModelVersion.V3 => "generalv3",
            ModelVersion.V3_5 => "generalv3.5",
            _ => throw new ArgumentOutOfRangeException(nameof(version), version, null),
        };
    }

    /// <summary>
    /// Specify the model version: 'general': v1.5, 'generalv2': v2, 'generalv3': v3, 'generalv3.5': v3.5
    /// </summary>
    /// <remarks>
    /// Note: Different values correspond to different URLs!
    /// </remarks>
    [JsonPropertyName("domain")]
    public required string Domain { get; set; }
}

/// <summary>
/// Model versions for Spark Desk Large Model.
/// </summary>
public enum ModelVersion
{
    /// <summary>
    /// v1.5 version
    /// </summary>
    V1_5,

    /// <summary>
    /// v2 version
    /// </summary>
    V2,

    /// <summary>
    /// v3 version
    /// </summary>
    V3,

    /// <summary>
    /// v3.5 version
    /// </summary>
    V3_5,
}